package br.eng.eliseu.gwt.aconchego.camera.server.service;

import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;
import java.util.TimeZone;

import javax.persistence.EntityManager;
import javax.persistence.Query;

import br.eng.eliseu.gwt.aconchego.camera.client.service.LoginService;
import br.eng.eliseu.gwt.aconchego.camera.module.AcessoCam;
import br.eng.eliseu.gwt.aconchego.camera.module.GrupoEnum;
import br.eng.eliseu.gwt.aconchego.camera.module.StatusEnum;
import br.eng.eliseu.gwt.aconchego.camera.module.Usuario;
import br.eng.eliseu.gwt.aconchego.camera.server.EMF;

import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class LoginServiceImpl extends RemoteServiceServlet implements LoginService{

	private static final long serialVersionUID = 5677206044656225280L;

	@SuppressWarnings("unchecked")
	public Number contaUsuarios() throws Exception {
		List<Usuario> lista = new ArrayList<Usuario>();

		EntityManager manager = EMF.currentEntityManager();
		try {
			Query q;
			manager.getTransaction().begin();
			q = manager.createNamedQuery("usuario.selectTudo");

			lista = (List<Usuario>) q.getResultList();
			
			manager.getTransaction().commit();

		} catch (Exception e) {
			System.out.println( e.getMessage() );
		} finally {
			EMF.closeEntityManager();
		}

		return lista.size();
	}

	@SuppressWarnings("unchecked")
	public AcessoCam login(String emailLogin, String senhaLogin) throws Exception {
		AcessoCam usuarioLogin = new AcessoCam();
		EntityManager manager = EMF.currentEntityManager();
		try {
			Query q;
			manager.getTransaction().begin();
			
			// --- Busca Usuario
			List<Usuario> lista = new ArrayList<Usuario>();
			q = manager.createNamedQuery("usuario.selectPorEmailSenha");
			q.setParameter("email", emailLogin);
			q.setParameter("senha", senhaLogin);

			lista = (List<Usuario>) q.getResultList();
			if (lista.size()==0){
				throw new Exception("Usuario ou senha invalidos");
			}
			
			// --- Busca Acessos
			Usuario u = new Usuario();
			u = lista.get(0);
			List<AcessoCam> acesso = new ArrayList<AcessoCam>();
			q = manager.createNamedQuery("acessoCam.selectAcessoUsuario");
			q.setParameter("usuario", u);
			q.setParameter("statusUsuario", StatusEnum.ATIVO);
			
			acesso = (List<AcessoCam>) q.getResultList();
			if (lista.size()==0){
				throw new Exception("O usuario ("+u.getEmail()+") nao tem informacoes sobre acesso as cameras");
			}
			
			if (acesso.size()<= 0){
				throw new Exception("Definicao de acesso do usuario nao foi encontrado");
			}
			usuarioLogin = acesso.get(0);
			
			manager.getTransaction().commit();

		} catch (Exception e) {
			System.out.println( e.getMessage() );
			throw new Exception(e.getMessage());
		} finally {
			EMF.closeEntityManager();
		}
		
		usuarioLogin.repopulaListCameras();

		try{
			verificaPermissaoAcesso(usuarioLogin, "LOGIN"); 
		} catch (Exception e){
			throw new Exception(e.getMessage());
		}

		return usuarioLogin;
	}

	/*
	 * Metodo que verifica se o usuario esta dentro do periodo  
	 * especificado
	 * 
	 */
	public Boolean verificaPermissaoAcesso( AcessoCam acesso, String origem ) throws Exception{
		
		// --- Se nao esta ativo, nao libera
		if ( acesso.getStatus().equals(StatusEnum.INATIVO)){
			throw new Exception("Este usuario esta INATIVO");
		}
		
		// --- Se � administrador ja retorna que esta liberado
		if ( acesso.getGrupo().equals(GrupoEnum.ADMINISTRADOR)){
			return true;
		}
		
		// --- Se nao informou intervalo, � porque esta livre
		if ( (acesso.getPeriodoInicio()==null && acesso.getPeriodoFim()==null) || 
			  ("".equals(acesso.getPeriodoInicio()) && "".equals(acesso.getPeriodoFim())) ){
			return true;
		}

		
		TimeZone tz = TimeZone.getTimeZone("America/Sao_Paulo");  
        TimeZone.setDefault(tz);  
        Calendar ca = GregorianCalendar.getInstance(tz);  
        
        
		
        // --- Se for final de seman nao libera
        if ( ca.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY || ca.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY ){
        	throw new Exception("Seu acesso so e permitido nos dias uteis");
        }
        
        Date agora = ca.getTime();
        SimpleDateFormat  ds = new SimpleDateFormat("HH:mm");    
        String hAgora = ds.format(agora);   
        String hInicio = ds.format(acesso.getPeriodoInicio());
        String hFim = ds.format(acesso.getPeriodoFim());
        
        if ( !(hInicio.compareTo(hAgora) < 0 && hFim.compareTo(hAgora) > 0) ){
        	throw new Exception("Voce esta fora do seu horario de acesso ( "+hInicio+" as "+hFim+" )");
        }
        
		return true;
	}
	
}


